package com.example.blog.web;

import com.example.blog.annotation.Distinct;
import com.example.blog.annotation.LoginUser;
import com.example.blog.annotation.RequiresPermission;
import com.example.blog.dao.UserInfoRepository;
import com.example.blog.dto.LoginUserDto;
import com.example.blog.dto.UserDto;
import com.example.blog.dto.UserInfoDto;
import com.example.blog.dto.VerificationCodeDto;
import com.example.blog.entity.UserInfo;
import com.example.blog.exception.NewWifiLoginException;
import com.example.blog.service.UserInfoService;
import com.example.blog.util.*;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;

import static com.example.blog.constant.ApiUrlConstants.ADMIN;
import static com.example.blog.constant.ApiUrlConstants.USER;
import static com.example.blog.constant.Constant.*;
import static com.example.blog.util.TransformationIp.getRealIp;


/**
 * 表控制层
 *
 * @author makejava
 * @since 2021-08-10 16:14:21
 */
@RestController
@RequestMapping("userInfo")
@Api(value = "人员信息接口", tags = "人员信息接口")
public class ManageInfoController {
    /**
     * 服务对象
     */
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private RedisUtil redisUtil;
    /**
     * 统一登录
     *
     * @param
     * @return
     */
    @PostMapping(value = "auth",produces="application/json")
    @ApiOperation(value = "统一登录")
    @ResponseBody
    public Result loginManage(HttpServletRequest httpServletRequest,
                              @RequestBody LoginUserDto loginUserDto) throws Exception {
        HashMap map = new HashMap();
        if(loginUserDto.getAccount() == null || "".equals(loginUserDto.getAccount())
                || "".equals(loginUserDto.getPassword()) || loginUserDto.getPassword() == null){
            return Result.failure(10003,"用户名或密码为空");
        }
        map = userInfoService.getToken(loginUserDto,httpServletRequest);
        if(map == null){
            return Result.failure(USER_NOT_FOUND,"用户不存在");
        }
        return Result.ok().setData(map);

    }
    /**
     * 用户标准注册
     *
     * @param
     * @return
     */
    @PostMapping(value = "register",produces="application/json")
    @ApiOperation(value = "用户标准注册")
    @ResponseBody
    @Distinct
    public Result register(HttpServletRequest httpServletRequest,
                           @RequestBody UserInfoDto userInfoDto) throws Exception {
        if(userInfoDto.getUsername() == null || "".equals(userInfoDto.getUsername())
                || "".equals(userInfoDto.getPassword()) || userInfoDto.getPassword() == null){
            return Result.failure(USERNAME_OR_NOTFOUND,"用户名或密码为空,请重新输入");
        }
        String realIp = getRealIp(httpServletRequest);
        HashMap map = new HashMap();
        UserInfo register = userInfoService.register(userInfoDto,realIp);
        if (register != null) {
            String token = UserTokenManager.generateToken(register.getId());
            map.put("Token",token);
            UserDto userDto = ModelMapperUtil.strictMap(userInfoDto, UserDto.class);
            userDto.setLoginIp(realIp); // 来源ip
            userDto.setLoginTime(new Date()); //登录时间
            redisUtil.setValue(token+register.getId(), JsonXMLUtils.obj2json(register)); // 存入缓存
            return Result.ok().setData(map);
        } else {
            return  Result.failure(USERNAME_REPEAT,"用户名已存在，请重新输入");
        }
    }

    /**
     * 忘记密码/修改密码
     *
     * @param
     * @return
     */
    @PostMapping(value = "retrieve",produces="application/json")
    @ApiOperation(value = "忘记密码/修改密码")
    @ResponseBody
    public Result retrieve(@RequestBody UserInfoDto userInfoDto) throws Exception {
        userInfoService.update(ModelMapperUtil.strictMap(userInfoDto, UserInfo.class));
        return Result.ok();
    }


    /**
     * 找回密码
     *
     * @param
     * @return
     */
    @PostMapping(value = "verification",produces="application/json")
    @ApiOperation(value = "找回密码")
    @ResponseBody
    public Result retrieve(@RequestBody VerificationCodeDto verificationCodeDto) throws Exception {
        if (redisUtil.exist(verificationCodeDto.getCode())) {
            if (verificationCodeDto.getUsername() != null && !verificationCodeDto.getUsername().equals("")) {
                String value = redisUtil.getValue(verificationCodeDto.getCode());
                UserInfoDto userInfoDto =JsonXMLUtils.json2obj(value, UserInfoDto.class);
                if (verificationCodeDto.getUsername().equals(userInfoDto.getUsername())) {
                    UserInfo userInfo = JsonXMLUtils.json2obj(value, UserInfo.class);
                    userInfo.setPassword(verificationCodeDto.getPassword());
                    // 修改密码
                    userInfoService.update(ModelMapperUtil.strictMap(userInfoDto, UserInfo.class));
                    redisUtil.delete(verificationCodeDto.getCode());
                    return Result.ok();
                }else {
                    return Result.failure(USERNAME_DIFFERENT,"用户名不正确，请重新填写");
                }
            }else {
                return Result.failure(USER_NOT_FOUND,"用户名不存在");
            }
        }
        return Result.failure(CODE_INVALID,"验证码已失效，请重新获取");
    }

    /**
     * 用户注销
     *
     * @param
     * @return
     */
    @GetMapping(value = "loginOut",produces="application/json")
    @ApiOperation(value = "用户注销")
    @ResponseBody
    public Result loginOut(@RequestHeader(value = "cloud-Auth-Token",required = false) String cloudAuthToken, @LoginUser String userId) throws Exception {
        if (StringUtils.isEmpty(userId)) {
            return Result.failure(USERNAME_Off_SITE,usernameOffSite);
        }
        if (cloudAuthToken != null && !cloudAuthToken.equals("")) {
            if (redisUtil.exist(cloudAuthToken+userId)) { // 缓存是否存在
                redisUtil.delete(cloudAuthToken+userId);
                return Result.ok();
            }else {
                return Result.failure(USERNAME_Off_SITE,usernameOffSite);
            }
        }else {
            return Result.failure(USER_NOT_LOGIN,"用户未登录");
        }
    }
    /**
     * 点击账号名可查询用户个人信息
     *
     * @param
     * @return
     */
    @GetMapping(value = "queryByUser",produces="application/json")
    @ApiOperation(value = "查询用户个人信息")
    @ResponseBody
    @RequiresPermission(roles = {ADMIN,USER})
    public Result queryOnlineByUser(@LoginUser String userId)  {
        if (StringUtils.isEmpty(userId)) {
            throw  new NewWifiLoginException("未登录");
        }
        return Result.ok().setData(userInfoService.queryByUserId(userId));
    }
}
